home *** CD-ROM | disk | FTP | other *** search
/ BMUG Revelations / BMUG Revelations.toast / Programming / Programming Languages / UCB Logo 3.0 / CSLS / pascal < prev    next >
Text File  |  1992-11-01  |  21KB  |  890 lines

  1. TO ACOUNT :ARRAY
  2. OUTPUT COUNT :ARRAY
  3. END
  4.  
  5. TO GARRAY :ARRAY :INDEX
  6. OP ITEM :INDEX+1 :ARRAY
  7. END
  8.  
  9. TO PARRAY :ARRAY :INDEX :VALUE
  10. SETITEM :INDEX+1 :ARRAY :VALUE
  11. END
  12.  
  13. TO ARGLIST
  14. LOCAL [NAMES TYPE VARFLAG]
  15. MAKE "VARFLAG "FALSE
  16. IFBE "VAR [MAKE "VARFLAG "TRUE]
  17. MAKE "NAMES COMMALIST [ID]
  18. MUSTBE ":
  19. MAKE "TYPE TOKEN
  20. IF EQUALP :TYPE "PACKED [MAKE "TYPE TOKEN]
  21. IFELSE EQUALP :TYPE "ARRAY [MAKE "TYPE ARRAYTYPE] [TYPECHECK :TYPE]
  22. FOREACH :NAMES [NEWARG ? :TYPE NEWLNAME ? :VARFLAG]
  23. IFBEELSE "|;| [ARGLIST] [MUSTBE "|)|]
  24. END
  25.  
  26. TO ARRAYCOPY :TOTARGET :FROMTARGET
  27. LOCAL [TO FROM]
  28. MAKE "TO THING FIRST :TOTARGET
  29. MAKE "FROM THING FIRST :FROMTARGET
  30. FOR [I 0 [(ACOUNT :FROM) - 1]] [PARRAY :TO :I GARRAY :FROM :I]
  31. END
  32.  
  33. TO ARRAYSIZE :TYPE
  34. OUTPUT REDUCE "PRODUCT MAP [LAST ?] LAST :TYPE
  35. END
  36.  
  37. TO ARRAYTYPE
  38. LOCAL [RANGES TYPE]
  39. MUSTBE "|[|
  40. MAKE "RANGES COMMALIST [RANGE]
  41. MUSTBE "|]|
  42. MUSTBE "OF
  43. MAKE "TYPE TOKEN
  44. TYPECHECK :TYPE
  45. OUTPUT LIST :TYPE :RANGES
  46. END
  47.  
  48. TO BLOCK
  49. LOCAL [BLOCKNAME CODEINTO]
  50. MAKE "BLOCKNAME GENSYM
  51. DEFINE :BLOCKNAME [[]]
  52. MAKE "CODEINTO :BLOCKNAME
  53. BLOCKBODY "END
  54. OUTPUT (LIST :BLOCKNAME)
  55. END
  56.  
  57. TO BLOCKBODY :ENDWORD
  58. CODE STATEMENT
  59. IFBEELSE "|;| [BLOCKBODY :ENDWORD] [MUSTBE :ENDWORD]
  60. END
  61.  
  62. TO BOOLTOINT :EXPR
  63. OUTPUT (SE [( IFELSE] :EXPR [[1] [0] )])
  64. END
  65.  
  66. TO CHARTOINT :EXPR
  67. OUTPUT (SE [( ASCII FIRST BF] :EXPR [)] )
  68. END
  69.  
  70. TO CHARTOPRINT :CHARVAL
  71. OUTPUT FIRST BF :CHARVAL
  72. END
  73.  
  74. TO CODE :STUFF
  75. IF EMPTYP :STUFF [STOP]
  76. DEFINE :CODEINTO LPUT :STUFF TEXT :CODEINTO
  77. END
  78.  
  79. TO COMMALIST :TEST [:SOFAR []]
  80. LOCAL [RESULT TOKEN]
  81. MAKE "RESULT RUN :TEST
  82. IF EMPTYP :RESULT [OUTPUT :SOFAR]
  83. MAKE "TOKEN TOKEN
  84. IF EQUALP :TOKEN ", [OUTPUT (COMMALIST :TEST (LPUT :RESULT :SOFAR))]
  85. MAKE "PEEKTOKEN :TOKEN
  86. OUTPUT LPUT :RESULT :SOFAR
  87. END
  88.  
  89. TO COMPILE :FILE
  90. LOCAL "ERROR
  91. IF NAMEP "PEEKCHAR [ERN "PEEKCHAR]
  92. IF NAMEP "PEEKTOKEN [ERN "PEEKTOKEN]
  93. OPENREAD :FILE
  94. SETREAD :FILE
  95. IGNORE ERROR
  96. CATCH "ERROR [PROGRAM]
  97. MAKE "ERROR ERROR
  98. IF NOT EMPTYP :ERROR ~
  99.    [IF NOT EQUALP FIRST :ERROR 19 ~
  100.        [PR FIRST BF :ERROR]]
  101. SETREAD []
  102. CLOSE :FILE
  103. END
  104.  
  105. TO COPYOFARRAY :TARGET
  106. LOCAL [TO FROM]
  107. MAKE "FROM THING FIRST :TARGET
  108. MAKE "TO ARRAY ACOUNT :FROM
  109. FOR [I 0 [(ACOUNT :FROM) - 1]] [PARRAY :TO :I GARRAY :FROM :I]
  110. END
  111.  
  112. TO FUNCTION
  113. LOCAL [PROGNAME OLDIDLIST ARGLIST TYPE]
  114. LOCAL "CODEINTO
  115. MAKE "PROGNAME TOKEN
  116. PUSH "IDLIST (LIST :PROGNAME "FUNCTION NEWLNAME :PROGNAME)
  117. MAKE "OLDIDLIST :IDLIST
  118. LOCAL "IDLIST
  119. MAKE "IDLIST :OLDIDLIST
  120. MAKE "ARGLIST []
  121. MAKE LNAME :PROGNAME []
  122. IFBE "|(| [ARGLIST]
  123. MUSTBE ":
  124. MAKE "TYPE TOKEN
  125. TYPECHECK :TYPE
  126. MAKE LNAME :PROGNAME FPUT :TYPE THING LNAME :PROGNAME
  127. MUSTBE "|;|
  128. DEFINE LNAME :PROGNAME (LIST :ARGLIST)
  129. MAKE "CODEINTO LNAME :PROGNAME
  130. CODE [LOCAL "RESULT]
  131. PROGRAM1
  132. CODE [OUTPUT :RESULT]
  133. MUSTBE "|;|
  134. END
  135.  
  136. TO GETCHAR
  137. LOCAL "CHAR
  138. IF NAMEP "PEEKCHAR [MAKE "CHAR :PEEKCHAR ERN "PEEKCHAR OUTPUT :CHAR]
  139. IF EOFP [OUTPUT CHAR 1]
  140. OUTPUT RC1
  141. END
  142.  
  143. TO GETTYPE :WORD
  144. LOCAL "RESULT
  145. MAKE "RESULT LNAME1 :WORD :IDLIST
  146. IF NOT EMPTYP :RESULT [OUTPUT ITEM 2 :RESULT]
  147. PRINT SE [UNRECOGNIZED IDENTIFIER] :WORD
  148. THROW "ERROR
  149. END
  150.  
  151. TO ID
  152. LOCAL "TOKEN
  153. MAKE "TOKEN TOKEN
  154. IF LETTERP ASCII FIRST :TOKEN [OUTPUT :TOKEN]
  155. MAKE "PEEKTOKEN :TOKEN
  156. OUTPUT []
  157. END
  158.  
  159. TO IFBE :WANTED :ACTION
  160. LOCAL "TOKEN
  161. MAKE "TOKEN TOKEN
  162. IF EQUALP :TOKEN :WANTED [RUN :ACTION STOP]
  163. MAKE "PEEKTOKEN :TOKEN
  164. END
  165.  
  166. TO IFBEELSE :WANTED :ACTION :ELSE
  167. LOCAL "TOKEN
  168. MAKE "TOKEN TOKEN
  169. IF EQUALP :TOKEN :WANTED [RUN :ACTION STOP]
  170. MAKE "PEEKTOKEN :TOKEN
  171. RUN :ELSE
  172. END
  173.  
  174. TO LETTERP :CODE
  175. IF AND (:CODE > 64) (:CODE < 91) [OUTPUT "TRUE]
  176. OUTPUT AND (:CODE > 96) (:CODE < 123)
  177. END
  178.  
  179. TO LINDEX :BOUNDS :INDEX
  180. OUTPUT LINDEX1 (OFFSET PINTEGER FIRST :INDEX FIRST FIRST :BOUNDS) ~
  181.                BF :BOUNDS BF :INDEX
  182. END
  183.  
  184. TO LINDEX1 :SOFAR :BOUNDS :INDEX
  185. IF EMPTYP :BOUNDS [OUTPUT :SOFAR]
  186. OUTPUT LINDEX1 (NEXTINDEX :SOFAR ~
  187.                           LAST FIRST :BOUNDS ~
  188.                           PINTEGER FIRST :INDEX ~
  189.                           FIRST FIRST :BOUNDS) ~
  190.                BF :BOUNDS BF :INDEX
  191. END
  192.  
  193. TO LNAME :WORD
  194. LOCAL "RESULT
  195. MAKE "RESULT LNAME1 :WORD :IDLIST
  196. IF NOT EMPTYP :RESULT [OUTPUT ITEM 3 :RESULT]
  197. PRINT SE [UNRECOGNIZED IDENTIFIER] :WORD
  198. THROW "ERROR
  199. END
  200.  
  201. TO LNAME1 :WORD :LIST
  202. IF EMPTYP :LIST [OUTPUT []]
  203. IF EQUALP :WORD FIRST FIRST :LIST [OUTPUT FIRST :LIST]
  204. OUTPUT LNAME1 :WORD BF :LIST
  205. END
  206.  
  207. TO LPUSH :STACK :STUFF
  208. MAKE :STACK LPUT :STUFF THING :STACK
  209. END
  210.  
  211. TO MULT :A :B
  212. OUTPUT (SE [( PRODUCT] :A :B [)] )
  213. END
  214.  
  215. TO MUSTBE :WANTED
  216. LOCAL "TOKEN
  217. MAKE "TOKEN TOKEN
  218. IF EQUALP :TOKEN :WANTED [STOP]
  219. PRINT (SE "EXPECTED :WANTED "GOT :TOKEN)
  220. THROW "ERROR
  221. END
  222.  
  223. TO NEWARG :PNAME :TYPE :LNAME :VARFLAG
  224. IF RESERVEDP :PNAME [PR SE :PNAME [RESERVED WORD] THROW "ERROR]
  225. PUSH "IDLIST IFELSE :VARFLAG ~
  226.                     [(LIST :PNAME "VAR :LNAME :TYPE)] ~
  227.                     [(LIST :PNAME :TYPE :LNAME)]
  228. LPUSH "ARGLIST :LNAME
  229. LPUSH LNAME :PROGNAME IFELSE :VARFLAG [LIST "VAR :TYPE] [:TYPE]
  230. END
  231.  
  232. TO NEWLNAME :WORD
  233. IF MEMBERP :WORD :NAMESUSED [OUTPUT GENSYM]
  234. IF NAMEP WORD "% :WORD [OUTPUT GENSYM]
  235. PUSH "NAMESUSED :WORD
  236. OUTPUT WORD "% :WORD
  237. END
  238.  
  239. TO NEWVAR :PNAME :TYPE :LNAME
  240. IF RESERVEDP :PNAME [PR SE :PNAME [RESERVED WORD] THROW "ERROR]
  241. PUSH "IDLIST (LIST :PNAME :TYPE :LNAME)
  242. CODE LIST "LOCAL WORD "" :LNAME
  243. IF LISTP :TYPE [CODE (LIST "MAKE WORD "" :LNAME "ARRAY ARRAYSIZE :TYPE)]
  244. END
  245.  
  246. TO NEXTINDEX :OLD :FACTOR :NEW :OFFSET
  247. OUTPUT (SE [( SUM] (MULT :OLD :FACTOR) (OFFSET :NEW :OFFSET) [)] )
  248. END
  249.  
  250. TO NUMBER :NUM
  251. LOCAL "CHAR
  252. MAKE "CHAR GETCHAR
  253. IF EQUALP :CHAR ". ~
  254.    [MAKE "CHAR GETCHAR ~
  255.     IFELSE EQUALP :CHAR ". ~
  256.            [MAKE "PEEKTOKEN ".. OUTPUT :NUM] ~
  257.            [MAKE "PEEKCHAR :CHAR OUTPUT NUMBER WORD :NUM ".]]
  258. IF EQUALP :CHAR "E [OUTPUT NUMBER WORD :NUM TWOCHAR "E [+ -]]
  259. IF NUMBERP :CHAR [OUTPUT NUMBER WORD :NUM :CHAR]
  260. MAKE "PEEKCHAR :CHAR
  261. OUTPUT :NUM
  262. END
  263.  
  264. TO NUMTYPE :NUMBER
  265. IF MEMBERP ". :NUMBER [OUTPUT "REAL]
  266. IF MEMBERP "E :NUMBER [OUTPUT "REAL]
  267. OUTPUT "INTEGER
  268. END
  269.  
  270. TO OFFSET :A :B
  271. OUTPUT (SE [( DIFFERENCE] :A :B [)] )
  272. END
  273.  
  274. TO OPSETUP
  275. PPROP "|=| "BINARY [EQUALP 2 [BOOLEAN []] 1]
  276. PPROP "|<>| "BINARY [[NOT EQUALP] 2 [BOOLEAN []] 1]
  277. PPROP "|<| "BINARY [LESSP 2 [BOOLEAN []] 1]
  278. PPROP "|>| "BINARY [GREATERP 2 [BOOLEAN []] 1]
  279. PPROP "|<=| "BINARY [[NOT GREATERP] 2 [BOOLEAN []] 1]
  280. PPROP "|>=| "BINARY [[NOT LESSP] 2 [BOOLEAN []] 1]
  281. PPROP "|+| "BINARY [SUM 2 2]
  282. PPROP "|-| "BINARY [DIFFERENCE 2 2]
  283. PPROP "OR "BINARY [OR 2 [BOOLEAN BOOLEAN] 2]
  284. PPROP "|*| "BINARY [PRODUCT 2 3]
  285. PPROP "|/| "BINARY [QUOTIENT 2 [REAL []] 3]
  286. PPROP "DIV "BINARY [[INT QUOTIENT] 2 [INTEGER INTEGER] 3]
  287. PPROP "MOD "BINARY [REMAINDER 2 [INTEGER INTEGER] 3]
  288. PPROP "AND "BINARY [AND 2 [BOOLEAN BOOLEAN] 3]
  289. PPROP "|+| "UNARY [[] 1 4]
  290. PPROP "|-| "UNARY [MINUS 1 4]
  291. PPROP "NOT "UNARY [NOT 1 [BOOLEAN BOOLEAN] 4]
  292. MAKE "IDLIST [[TRUNC FUNCTION INT] ~
  293.               [ROUND FUNCTION ROUND] [RANDOM FUNCTION RANDOM]]
  294. MAKE "INT [INTEGER REAL]
  295. MAKE "ROUND [INTEGER REAL]
  296. MAKE "RANDOM [INTEGER INTEGER]
  297. END
  298.  
  299. TO PARRAYASSIGN :NAME :TYPE :TARGET
  300. LOCAL [RIGHT RTYPE RLNAME RTARGET]
  301. MAKE "RIGHT TOKEN
  302. IF EQUALP FIRST :RIGHT "' [OUTPUT PSTRINGASSIGN :TARGET :TYPE (BL BF :RIGHT)]
  303. MAKE "RTYPE GETTYPE :RIGHT
  304. MAKE "RLNAME LNAME :RIGHT
  305. IFELSE EQUALP :RTYPE "VAR [PVARRIGHT] [MAKE "RTARGET (LIST :RLNAME)]
  306. IF EQUALP :TYPE :RTYPE [OUTPUT (LIST "ARRAYCOPY :TARGET :RTARGET)]
  307. PR (SE "ARRAYS :NAME "AND :RIGHT [UNEQUAL TYPES])
  308. THROW "ERROR
  309. END
  310.  
  311. TO PARRAYDATA :PNAME :TYPE :TARGET
  312. LOCAL "INDEX
  313. MUSTBE "|[|
  314. MAKE "INDEX COMMALIST [PEXPR]
  315. MUSTBE "|]|
  316. MAKE "INDEX LINDEX LAST :TYPE :INDEX
  317. MAKE "TYPE FIRST :TYPE
  318. MAKE "TARGET SE :TARGET :INDEX
  319. OUTPUT PMAYBECHAR :TYPE (LIST "PTHING :TARGET)
  320. END
  321.  
  322. TO PASSIGN
  323. LOCAL [NAME TYPE INDEX VALUE LNAME TARGET]
  324. MAKE "NAME TOKEN
  325. MAKE "INDEX []
  326. IFBE "|[| [MAKE "INDEX COMMALIST [PEXPR] MUSTBE "|]|]
  327. MUSTBE "|:=|
  328. MAKE "LNAME LNAME :NAME
  329. MAKE "TYPE GETTYPE :NAME
  330. OUTPUT PASSIGN1
  331. END
  332.  
  333. TO PASSIGN1
  334. IFELSE EQUALP :TYPE "VAR [PVARASSIGN :NAME] [MAKE "TARGET (LIST :LNAME)]
  335. IF AND (LISTP :TYPE) (EMPTYP :INDEX) [OUTPUT PARRAYASSIGN :NAME :TYPE :TARGET]
  336. IF LISTP :TYPE [MAKE "INDEX LINDEX LAST :TYPE :INDEX MAKE "TYPE FIRST :TYPE]
  337. IF NOT EMPTYP :INDEX [MAKE "TARGET SE :TARGET :INDEX]
  338. MAKE "VALUE PEXPR
  339. IF EQUALP :TYPE "REAL [MAKE "VALUE PREAL :VALUE]
  340. IF EQUALP :TYPE "INTEGER [MAKE "VALUE PINTEGER :VALUE]
  341. IF EQUALP :TYPE "CHAR [MAKE "VALUE PCHAR :VALUE]
  342. IF EQUALP :TYPE "BOOLEAN [MAKE "VALUE PBOOLEAN :VALUE]
  343. OUTPUT (SE (LIST "PMAKE :TARGET) :VALUE)
  344. END
  345.  
  346. TO PBOOLEAN :EXPR
  347. IF EQUALP FIRST :EXPR "BOOLEAN [OUTPUT LAST :EXPR]
  348. PR SE LAST :COND [NOT TRUE OR FALSE]
  349. THROW "ERROR
  350. END
  351.  
  352. TO PCHAR :EXPR
  353. IF EQUALP FIRST :EXPR "CHAR [OUTPUT LAST :EXPR]
  354. PR SE LAST :COND [NOT CHARACTER VALUE]
  355. THROW "ERROR
  356. END
  357.  
  358. TO PCHARDATA :TOKEN
  359. IF NOT EQUALP COUNT :TOKEN 3 [PR SE :TOKEN [NOT SINGLE CHARACTER] THROW "ERROR]
  360. OUTPUT LIST "CHAR WORD "" :TOKEN
  361. END
  362.  
  363. TO PCHECKTYPE :WANT :LEFT :RIGHT
  364. IF NOT EQUALP :WANT :LEFT [PR (SE :LEFT "ISN'T :WANT) THROW "ERROR]
  365. IF NOT EQUALP :WANT :RIGHT [PR (SE :RIGHT "ISN'T :WANT) THROW "ERROR]
  366. END
  367.  
  368. TO PCLOSE
  369. WHILE [(LAST FIRST :OPSTACK) > 0] [PPOPOP]
  370. IGNORE POP "OPSTACK
  371. MAKE "PARENLEVEL :PARENLEVEL - 1
  372. END
  373.  
  374. TO PDATA :TOKEN
  375. LOCAL [TYPE LNAME TARGET]
  376. IF EQUALP :TOKEN "TRUE [OUTPUT [BOOLEAN "TRUE]]
  377. IF EQUALP :TOKEN "FALSE [OUTPUT [BOOLEAN "FALSE]]
  378. IF EQUALP FIRST :TOKEN "' [OUTPUT PCHARDATA :TOKEN]
  379. IF NUMBERP :TOKEN [OUTPUT LIST NUMTYPE :TOKEN :TOKEN]
  380. MAKE "TYPE GETTYPE :TOKEN
  381. IF EMPTYP :TYPE [PR SE [UNDEFINED SYMBOL] :TOKEN THROW "ERROR]
  382. MAKE "LNAME LNAME :TOKEN
  383. IFELSE EQUALP :TYPE "VAR [PVARASSIGN :TOKEN] [MAKE "TARGET (LIST :LNAME)]
  384. IF EQUALP :TYPE "FUNCTION [OUTPUT PFUNCALL :TOKEN]
  385. IF LISTP :TYPE [OUTPUT PARRAYDATA :TOKEN :TYPE :TARGET]
  386. OUTPUT PMAYBECHAR :TYPE LIST "PTHING :TARGET
  387. END
  388.  
  389. TO PEXPR
  390. LOCAL [OPSTACK DATASTACK PARENLEVEL]
  391. MAKE "OPSTACK [[POPEN 1 0]]
  392. MAKE "DATASTACK []
  393. MAKE "PARENLEVEL 0
  394. OUTPUT PEXPR1
  395. END
  396.  
  397. TO PEXPR1
  398. LOCAL [TOKEN OP]
  399. MAKE "TOKEN TOKEN
  400. WHILE [EQUALP :TOKEN "|(|] [POPEN MAKE "TOKEN TOKEN]
  401. MAKE "OP PGETUNARY :TOKEN
  402. IF NOT EMPTYP :OP [OUTPUT PEXPROP :OP]
  403. PUSH "DATASTACK PDATA :TOKEN
  404. MAKE "TOKEN TOKEN
  405. WHILE [AND (:PARENLEVEL > 0) (EQUALP :TOKEN "|)| )] [PCLOSE MAKE "TOKEN TOKEN]
  406. MAKE "OP PGETBINARY :TOKEN
  407. IF NOT EMPTYP :OP [OUTPUT PEXPROP :OP]
  408. MAKE "PEEKTOKEN :TOKEN
  409. PCLOSE
  410. IF NOT EMPTYP :OPSTACK [PR [TOO MANY OPERATORS] THROW "ERROR]
  411. IF NOT EMPTYP BF :DATASTACK [PR [TOO MANY OPERANDS] THROW "ERROR]
  412. OUTPUT POP "DATASTACK
  413. END
  414.  
  415. TO PEXPROP :OP
  416. WHILE [(LAST :OP) < (1 + LAST FIRST :OPSTACK)] [PPOPOP]
  417. PUSH "OPSTACK :OP
  418. OUTPUT PEXPR1
  419. END
  420.  
  421. TO PFOR
  422. LOCAL [VAR INIT STEP FINAL ACTION]
  423. MAKE "VAR TOKEN
  424. MUSTBE "|:=|
  425. MAKE "INIT PINTEGER PEXPR
  426. MAKE "STEP 1
  427. IFBEELSE "DOWNTO [MAKE "STEP -1] [MUSTBE "TO]
  428. MAKE "FINAL PINTEGER PEXPR
  429. MUSTBE "DO
  430. MAKE "ACTION STATEMENT
  431. OUTPUT (LIST "FOR (LIST LNAME :VAR :INIT :FINAL :STEP) :ACTION)
  432. END
  433.  
  434. TO PFUNCALL :PNAME
  435. LOCAL [LNAME VARTYPES]
  436. MAKE "LNAME LNAME :PNAME
  437. MAKE "VARTYPES THING :LNAME
  438. IF EMPTYP BF :VARTYPES [OUTPUT LIST FIRST :VARTYPES :LNAME]
  439. MUSTBE "|(|
  440. OUTPUT LIST FIRST :VARTYPES FPUT :LNAME PROCARGS BF :VARTYPES
  441. END
  442.  
  443. TO PFUNSET
  444. LOCAL [NAME TYPE INDEX VALUE LNAME TARGET]
  445. MAKE "NAME TOKEN
  446. MAKE "INDEX []
  447. IF NOT EQUALP :NAME :PROGNAME [PR SE [ASSIGN TO WRONG FUNCTION] :NAME THROW "ERROR]
  448. MUSTBE "|:=|
  449. MAKE "LNAME "RESULT
  450. MAKE "TYPE FIRST THING LNAME :NAME
  451. OUTPUT PASSIGN1
  452. END
  453.  
  454. TO PGETBINARY :TOKEN
  455. OUTPUT GPROP :TOKEN "BINARY
  456. END
  457.  
  458. TO PGETUNARY :TOKEN
  459. OUTPUT GPROP :TOKEN "UNARY
  460. END
  461.  
  462. TO PIF
  463. LOCAL [COND THEN ELSE]
  464. MAKE "COND PBOOLEAN PEXPR
  465. MUSTBE "THEN
  466. MAKE "THEN STATEMENT
  467. MAKE "ELSE []
  468. IFBE "ELSE [MAKE "ELSE STATEMENT]
  469. OUTPUT (SE "IFELSE :COND (LIST :THEN) (LIST :ELSE))
  470. END
  471.  
  472. TO PINTEGER :PVAL
  473. LOCAL "TYPE
  474. MAKE "TYPE FIRST :PVAL
  475. IF EQUALP :TYPE "INTEGER [OUTPUT LAST :PVAL]
  476. IF EQUALP :TYPE "BOOLEAN [OUTPUT BOOLTOINT LAST :PVAL]
  477. IF EQUALP :TYPE "CHAR [OUTPUT CHARTOINT LAST :PVAL]
  478. PR SE LAST :PVAL [ISN'T ORDINAL]
  479. THROW "ERROR
  480. END
  481.  
  482. TO PMAKE :TARGET :VALUE
  483. IFELSE EMPTYP BF :TARGET ~
  484.        [MAKE FIRST :TARGET :VALUE] ~
  485.        [PARRAY TARGETVAR FIRST :TARGET RUN BF :TARGET :VALUE]
  486. END
  487.  
  488. TO PMAYBECHAR :TYPE :VAL
  489. IF EQUALP :TYPE "CHAR [OUTPUT LIST "CHAR SE "PVARTOCHAR :VAL]
  490. OUTPUT LIST :TYPE :VAL
  491. END
  492.  
  493. TO PNEWTYPE :OP :LTYPE :RTYPE
  494. LOCAL "TYPE
  495. MAKE "TYPE (IFELSE (COUNT :OP) > 3 [ITEM 3 :OP] [[[] []]])
  496. IF EMPTYP :LTYPE [MAKE "LTYPE :RTYPE]
  497. IF NOT EMPTYP LAST :TYPE [PCHECKTYPE LAST :TYPE :LTYPE :RTYPE]
  498. IF AND (EQUALP :LTYPE "REAL) (EQUALP :RTYPE "INTEGER) [MAKE "RTYPE "REAL]
  499. IF AND (EQUALP :LTYPE "INTEGER) (EQUALP :RTYPE "REAL) [MAKE "LTYPE "REAL]
  500. IF NOT EQUALP :LTYPE :RTYPE [PR [TYPE CLASH] THROW "ERROR]
  501. IF EMPTYP LAST :TYPE ~
  502.    [IF NOT MEMBERP :RTYPE [INTEGER REAL] [PR [NONARITHMETIC TYPE] THROW "ERROR]]
  503. IF EMPTYP FIRST :TYPE [OUTPUT :RTYPE]
  504. OUTPUT FIRST :TYPE
  505. END
  506.  
  507. TO POPEN
  508. PUSH "OPSTACK [POPEN 1 0]
  509. MAKE "PARENLEVEL :PARENLEVEL + 1
  510. END
  511.  
  512. TO PPOPOP
  513. LOCAL [OP FUNCTION ARGS LEFT RIGHT TYPE]
  514. MAKE "OP POP "OPSTACK
  515. MAKE "FUNCTION FIRST :OP
  516. MAKE "ARGS FIRST BF :OP
  517. MAKE "RIGHT POP "DATASTACK
  518. MAKE "LEFT (IFELSE EQUALP :ARGS 2 [POP "DATASTACK] [[[] []]])
  519. MAKE "TYPE PNEWTYPE :OP FIRST :LEFT FIRST :RIGHT
  520. PUSH "DATASTACK LIST :TYPE (SE [(] :FUNCTION LAST :LEFT LAST :RIGHT [)] )
  521. END
  522.  
  523. TO PPROCCALL
  524. LOCAL [PNAME LNAME VARTYPES]
  525. MAKE "PNAME TOKEN
  526. MAKE "LNAME LNAME :PNAME
  527. MAKE "VARTYPES THING :LNAME
  528. IF EMPTYP :VARTYPES [OUTPUT (LIST :LNAME)]
  529. MUSTBE "|(|
  530. OUTPUT FPUT :LNAME PROCARGS :VARTYPES
  531. END
  532.  
  533. TO PREAL :PVAL
  534. IF EQUALP FIRST :PVAL "REAL [OUTPUT LAST :PVAL]
  535. OUTPUT PINTEGER :PVAL
  536. END
  537.  
  538. TO PREPEAT
  539. LOCAL [COND BLOCKNAME CODEINTO]
  540. MAKE "BLOCKNAME GENSYM
  541. DEFINE :BLOCKNAME [[]]
  542. MAKE "CODEINTO :BLOCKNAME
  543. BLOCKBODY "UNTIL
  544. MAKE "COND PBOOLEAN PEXPR
  545. OUTPUT (LIST "DO.UNTIL (LIST :BLOCKNAME) :COND)
  546. END
  547.  
  548. TO PRINTSIZE :SIZE :STUFF
  549. IF NOT (:SIZE > COUNT :STUFF) [OUTPUT :STUFF]
  550. OUTPUT PRINTSIZE :SIZE WORD "| | :STUFF
  551. END
  552.  
  553. TO PROCARG :TYPE
  554. LOCAL "RESULT
  555. IF EQUALP FIRST :TYPE "VAR [OUTPUT PROCVARARG LAST :TYPE]
  556. IF LISTP :TYPE [OUTPUT PROCARRAYARG :TYPE]
  557. MAKE "RESULT PEXPR
  558. IF EQUALP :TYPE "REAL [MAKE "RESULT PREAL :RESULT]
  559. IF EQUALP :TYPE "INTEGER [MAKE "RESULT PINTEGER :RESULT]
  560. IF EQUALP :TYPE "CHAR [MAKE "RESULT PCHAR :RESULT]
  561. IF EQUALP :TYPE "BOOLEAN [MAKE "RESULT PBOOLEAN :RESULT]
  562. OUTPUT :RESULT
  563. END
  564.  
  565. TO PROCARGS :TYPES
  566. LOCAL "NEXT
  567. IF EMPTYP :TYPES [MUSTBE "|)| OUTPUT []]
  568. MAKE "NEXT PROCARG FIRST :TYPES
  569. IF NOT EMPTYP BF :TYPES [MUSTBE ",]
  570. OUTPUT SE :NEXT PROCARGS BF :TYPES
  571. END
  572.  
  573. TO PROCARRAYARG :TYPE
  574. LOCAL [PNAME TYPE LNAME TARGET]
  575. MAKE "PNAME TOKEN
  576. MAKE "TYPE GETTYPE :PNAME
  577. MAKE "LNAME LNAME :PNAME
  578. IFELSE EQUALP :TYPE "VAR [PVARASSIGN] [MAKE "TARGET (LIST :LNAME)]
  579. OUTPUT LIST "COPYOFARRAY :TARGET
  580. END
  581.  
  582. TO PROCEDURE
  583. LOCAL [PROGNAME OLDIDLIST CODEINTO ARGLIST]
  584. MAKE "PROGNAME TOKEN
  585. PUSH "IDLIST (LIST :PROGNAME "PROCEDURE NEWLNAME :PROGNAME)
  586. MAKE "OLDIDLIST :IDLIST
  587. LOCAL "IDLIST
  588. MAKE "IDLIST :OLDIDLIST
  589. MAKE "CODEINTO LNAME :PROGNAME
  590. MAKE "ARGLIST []
  591. MAKE LNAME :PROGNAME []
  592. IFBE "|(| [ARGLIST]
  593. MUSTBE "|;|
  594. DEFINE LNAME :PROGNAME (LIST :ARGLIST)
  595. PROGRAM1
  596. MUSTBE "|;|
  597. END
  598.  
  599. TO PROCVARARG :FTYPE
  600. LOCAL [PNAME TYPE LNAME TARGET]
  601. MAKE "PNAME TOKEN
  602. MAKE "TYPE GETTYPE :PNAME
  603. MAKE "LNAME LNAME :PNAME
  604. IFELSE EQUALP :TYPE "VAR [PVARASSIGN :PNAME] [MAKE "TARGET (LIST :LNAME)]
  605. IF AND (LISTP :TYPE) (WORDP :FTYPE) [OUTPUT PROCVARARGARRAY :FTYPE :TYPE :TARGET]
  606. IF NOT EQUALP :TYPE :FTYPE [PR SE :PNAME [ARG WRONG TYPE] THROW "ERROR]
  607. OUTPUT (LIST :TARGET)
  608. END
  609.  
  610. TO PROCVARARGARRAY :FTYPE :TYPE :TARGET
  611. IF NOT EQUALP :FTYPE FIRST :TYPE [PR SE :PNAME [ARG WRONG TYPE] THROW "ERROR]
  612. LOCAL "INDEX
  613. MUSTBE "|[|
  614. MAKE "INDEX COMMALIST [PEXPR]
  615. MUSTBE "|]|
  616. MAKE "INDEX LINDEX LAST :TYPE :INDEX
  617. OUTPUT (LIST SE :TARGET :INDEX)
  618. END
  619.  
  620. TO PROGRAM
  621. LOCAL [PROGNAME OLDIDLIST NAMESUSED CODEINTO]
  622. MAKE "NAMESUSED []
  623. MUSTBE "PROGRAM
  624. MAKE "PROGNAME TOKEN
  625. MUSTBE "|(|
  626. IGNORE COMMALIST [ID]
  627. MUSTBE "|)|
  628. MUSTBE "|;|
  629. IF NOT NAMEP "IDLIST [OPSETUP]
  630. MAKE "OLDIDLIST :IDLIST
  631. LOCAL "IDLIST
  632. MAKE "IDLIST :OLDIDLIST
  633. PUSH "IDLIST (LIST :PROGNAME "PROGRAM NEWLNAME :PROGNAME)
  634. DEFINE LNAME :PROGNAME [[]]
  635. MAKE "CODEINTO LNAME :PROGNAME
  636. PROGRAM1
  637. MUSTBE ".
  638. END
  639.  
  640. TO PROGRAM1
  641. IFBE "VAR [VARPART]
  642. TRYPROCPART
  643. MUSTBE "BEGIN
  644. BLOCKBODY "END
  645. END
  646.  
  647. TO PRUN :PROGNAME
  648. RUN FPUT WORD "% :PROGNAME []
  649. END
  650.  
  651. TO PSTRINGASSIGN :TARGET :TYPE :STRING
  652. IF NOT EQUALP FIRST :TYPE "CHAR [STRINGLOSE]
  653. IF NOT EMPTYP BF LAST :TYPE [STRINGLOSE]
  654. IF NOT EQUALP (LAST FIRST LAST :TYPE) (COUNT :STRING) [STRINGLOSE]
  655. OUTPUT (LIST "STRINGCOPY :TARGET WORD "" :STRING)
  656. END
  657.  
  658. TO PTHING :TARGET
  659. IF EMPTYP BF :TARGET [OUTPUT THING FIRST :TARGET]
  660. OUTPUT GARRAY TARGETVAR FIRST :TARGET RUN BF :TARGET
  661. END
  662.  
  663. TO PUSH :STACK :ITEM
  664. MAKE :STACK FPUT :ITEM THING :STACK
  665. END
  666.  
  667. TO PVARASSIGN :NAME
  668. LOCAL "ID
  669. MAKE "ID LNAME1 :NAME :IDLIST
  670. MAKE "TYPE LAST :ID
  671. MAKE "TARGET WORD ": :LNAME
  672. END
  673.  
  674. TO PVARRIGHT
  675. LOCAL "ID
  676. MAKE "ID LNAME1 :RIGHT :IDLIST
  677. MAKE "RTYPE LAST :ID
  678. MAKE "RTARGET WORD ": :RLNAME
  679. END
  680.  
  681. TO PVARTOCHAR :VALUE
  682. IF NUMBERP :VALUE [OUTPUT CHAR :VALUE]
  683. OUTPUT :VALUE
  684. END
  685.  
  686. TO PWHILE
  687. LOCAL [COND ACTION]
  688. MAKE "COND PBOOLEAN PEXPR
  689. MUSTBE "DO
  690. MAKE "ACTION STATEMENT
  691. OUTPUT (LIST "WHILE :COND :ACTION)
  692. END
  693.  
  694. TO PWRITE
  695. MUSTBE "|(|
  696. OUTPUT (SE [( TYPE] PWRITE1 [)] )
  697. END
  698.  
  699. TO PWRITE1
  700. LOCAL [RESULT TOKEN]
  701. MAKE "RESULT PWRITE2
  702. MAKE "TOKEN TOKEN
  703. IF EQUALP :TOKEN "|)| [OUTPUT :RESULT]
  704. IF NOT EQUALP :TOKEN ", [PR SE [EXPECTED , GOT] :TOKEN THROW "ERROR]
  705. OUTPUT SE :RESULT PWRITE1
  706. END
  707.  
  708. TO PWRITE2
  709. LOCAL "RESULT
  710. MAKE "RESULT PWRITE3
  711. IFBE ": [MAKE "RESULT (SE "PRINTSIZE TOKEN BF BF :RESULT)]
  712. OUTPUT :RESULT
  713. END
  714.  
  715. TO PWRITE3
  716. LOCAL [TOKEN RESULT]
  717. MAKE "TOKEN TOKEN
  718. IF EQUALP FIRST :TOKEN "' [OUTPUT (LIST "PRINTSIZE 1 "FIRST (LIST BL BF :TOKEN))]
  719. MAKE "PEEKTOKEN :TOKEN
  720. MAKE "RESULT PEXPR
  721. IF EQUALP FIRST :RESULT "CHAR [OUTPUT SE [PRINTSIZE 1 CHARTOPRINT] LAST :RESULT]
  722. IF EQUALP FIRST :RESULT "BOOLEAN [OUTPUT SE [PRINTSIZE 1] LAST :RESULT]
  723. IF EQUALP FIRST :RESULT "INTEGER [OUTPUT SE [PRINTSIZE 10] LAST :RESULT]
  724. OUTPUT SE [PRINTSIZE 20] LAST :RESULT
  725. END
  726.  
  727. TO PWRITELN
  728. LOCAL "TOKEN
  729. MAKE "TOKEN TOKEN
  730. MAKE "PEEKTOKEN :TOKEN
  731. IF NOT EQUALP :TOKEN "|(| [OUTPUT [PRINT []]]
  732. OUTPUT SE PWRITE [PRINT []]
  733. END
  734.  
  735. TO RANGE
  736. LOCAL [FIRST LAST]
  737. MAKE "FIRST RANGE1
  738. MUSTBE "..
  739. MAKE "LAST RANGE1
  740. IF :FIRST > :LAST ~  
  741.    [PR (SE [ARRAY BOUNDS NOT INCREASING:] :FIRST ".. :LAST) THROW "ERROR]
  742. OUTPUT LIST :FIRST (1 + :LAST - :FIRST)
  743. END
  744.  
  745. TO RANGE1
  746. LOCAL "BOUND
  747. MAKE "BOUND TOKEN
  748. IF EQUALP FIRST :BOUND "' [OUTPUT ASCII FIRST BF :BOUND]
  749. IF EQUALP :BOUND "|-| [MAKE "BOUND MINUS TOKEN]
  750. IF EQUALP :BOUND INT :BOUND [OUTPUT :BOUND]
  751. PR SE [ARRAY BOUND NOT ORDINAL:] :BOUND
  752. THROW "ERROR
  753. END
  754.  
  755. TO RC1
  756. LOCAL "RESULT
  757. MAKE "RESULT RC
  758. TYPE :RESULT
  759. OUTPUT :RESULT
  760. END
  761.  
  762. TO RESERVEDP :WORD
  763. OUTPUT MEMBERP :WORD [AND ARRAY BEGIN CASE CONST DIV DO DOWNTO ELSE END ~
  764.                       FILE FOR FORWARD FUNCTION GOTO IF IN LABEL MOD NIL ~
  765.                       NOT OF PACKED PROCEDURE PROGRAM RECORD REPEAT SET ~
  766.                       THEN TO TYPE UNTIL VAR WHILE WITH]
  767. END
  768.  
  769. TO SKIPCOMMENT
  770. IF EQUALP GETCHAR "|}| [STOP]
  771. SKIPCOMMENT
  772. END
  773.  
  774. TO STATEMENT
  775. LOCAL [TOKEN TYPE]
  776. MAKE "TOKEN TOKEN
  777. IF EQUALP :TOKEN "BEGIN [OUTPUT BLOCK]
  778. IF EQUALP :TOKEN "FOR [OUTPUT PFOR]
  779. IF EQUALP :TOKEN "IF [OUTPUT PIF]
  780. IF EQUALP :TOKEN "WHILE [OUTPUT PWHILE]
  781. IF EQUALP :TOKEN "REPEAT [OUTPUT PREPEAT]
  782. IF EQUALP :TOKEN "WRITE [OUTPUT PWRITE]
  783. IF EQUALP :TOKEN "WRITELN [OUTPUT PWRITELN]
  784. MAKE "PEEKTOKEN :TOKEN
  785. IF MEMBERP :TOKEN [|;| END UNTIL] [OUTPUT []]
  786. MAKE "TYPE GETTYPE :TOKEN
  787. IF EMPTYP :TYPE [PR SE :TOKEN [CAN'T BEGIN STATEMENT] THROW "ERROR]
  788. IF EQUALP :TYPE "PROCEDURE [OUTPUT PPROCCALL]
  789. IF EQUALP :TYPE "FUNCTION [OUTPUT PFUNSET]
  790. OUTPUT PASSIGN
  791. END
  792.  
  793. TO STRING :STRING
  794. LOCAL "CHAR
  795. MAKE "CHAR GETCHAR
  796. IF NOT EQUALP :CHAR "' [OUTPUT STRING WORD :STRING :CHAR]
  797. MAKE "CHAR GETCHAR
  798. IF EQUALP :CHAR "' [OUTPUT STRING WORD :STRING :CHAR]
  799. MAKE "PEEKCHAR :CHAR
  800. OUTPUT WORD :STRING "'
  801. END
  802.  
  803. TO STRINGCOPY :TOTARGET :FROM
  804. LOCAL [I TO]
  805. MAKE "TO THING FIRST :TOTARGET
  806. MAKE "I 0
  807. FOREACH :FROM [PARRAY :TO :I (WORD "' ? "') MAKE "I :I + 1]
  808. END
  809.  
  810. TO STRINGLOSE
  811. PR SE :NAME [NOT STRING ARRAY OR WRONG SIZE]
  812. THROW "ERROR
  813. END
  814.  
  815. TO TARGETVAR :WORD
  816. IF EQUALP FIRST :WORD ": [OUTPUT THING THING BF :WORD]
  817. OUTPUT THING :WORD
  818. END
  819.  
  820. TO TOKEN
  821. LOCAL [TOKEN CHAR]
  822. IF NAMEP "PEEKTOKEN [MAKE "TOKEN :PEEKTOKEN ERN "PEEKTOKEN OUTPUT :TOKEN]
  823. MAKE "CHAR GETCHAR
  824. IF EQUALP :CHAR "|{| [SKIPCOMMENT OUTPUT TOKEN]
  825. IF EQUALP :CHAR CHAR 32 [OUTPUT TOKEN]
  826. IF EQUALP :CHAR CHAR 13 [OUTPUT TOKEN]
  827. IF EQUALP :CHAR CHAR 10 [OUTPUT TOKEN]
  828. IF EQUALP :CHAR "' [OUTPUT STRING "']
  829. IF MEMBERP :CHAR [+ - * / = ( , ) |[| |]| |;|] [OUTPUT :CHAR]
  830. IF EQUALP :CHAR "|<| [OUTPUT TWOCHAR "|<| [= >]]
  831. IF EQUALP :CHAR "|>| [OUTPUT TWOCHAR "|>| [=]]
  832. IF EQUALP :CHAR ". [OUTPUT TWOCHAR ". [.]]
  833. IF EQUALP :CHAR ": [OUTPUT TWOCHAR ": [=]]
  834. IF NUMBERP :CHAR [OUTPUT NUMBER :CHAR]
  835. IF LETTERP ASCII :CHAR [OUTPUT TOKEN1 UC :CHAR]
  836. PR SE [UNRECOGNIZED CHARACTER:] :CHAR
  837. THROW "ERROR
  838. END
  839.  
  840. TO TOKEN1 :TOKEN
  841. LOCAL "CHAR
  842. MAKE "CHAR GETCHAR
  843. IF OR LETTERP ASCII :CHAR NUMBERP :CHAR [OUTPUT TOKEN1 WORD :TOKEN UC :CHAR]
  844. MAKE "PEEKCHAR :CHAR
  845. OUTPUT :TOKEN
  846. END
  847.  
  848. TO TRYPROCPART
  849. IFBEELSE "PROCEDURE ~
  850.          [PROCEDURE TRYPROCPART] ~
  851.          [IFBE "FUNCTION [FUNCTION TRYPROCPART]]
  852. END
  853.  
  854. TO TWOCHAR :OLD :OK
  855. LOCAL "CHAR
  856. MAKE "CHAR GETCHAR
  857. IF MEMBERP :CHAR :OK [OUTPUT WORD :OLD :CHAR]
  858. MAKE "PEEKCHAR :CHAR
  859. OUTPUT :OLD
  860. END
  861.  
  862. TO TYPECHECK :TYPE
  863. IF MEMBERP :TYPE [REAL INTEGER CHAR BOOLEAN] [STOP]
  864. PRINT SE [UNDEFINED TYPE] :TYPE
  865. THROW "ERROR
  866. END
  867.  
  868. TO UC :CHAR
  869. LOCAL "CODE
  870. MAKE "CODE ASCII :CHAR
  871. IF OR (:CODE < 97) (:CODE > 122) [OUTPUT :CHAR]
  872. OUTPUT CHAR :CODE - 32
  873. END
  874.  
  875. TO VARPART
  876. LOCAL [TOKEN NAMELIST]
  877. MAKE "TOKEN TOKEN
  878. MAKE "PEEKTOKEN :TOKEN
  879. IF RESERVEDP :TOKEN [STOP]
  880. MAKE "NAMELIST COMMALIST [ID]
  881. MUSTBE ":
  882. MAKE "TOKEN TOKEN
  883. IF EQUALP :TOKEN "PACKED [MAKE "TOKEN TOKEN]
  884. IFELSE EQUALP :TOKEN "ARRAY [MAKE "TOKEN ARRAYTYPE] [TYPECHECK :TOKEN]
  885. MUSTBE "|;|
  886. FOREACH :NAMELIST [NEWVAR ? :TOKEN NEWLNAME ?]
  887. VARPART
  888. END
  889.  
  890.